package com.zyh.scs.admin.utils;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zyh.scs.admin.api.constant.open.OpenResponseCode;
import com.zyh.scs.admin.api.dto.open.OpenAPIVerifyDTO;
import com.zyh.scs.admin.api.entity.UserCation;
import com.zyh.scs.admin.mapper.UserCationMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author hwh
 * @ClassName: 请求头工具类$
 * @Description: $
 * @Date $
 * @Version 1.0
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class HeaderUtil {

    private final OtherThingHelper callbackHelper;

    public static HeaderInfo getHeaderInfo(HttpServletRequest request) {
        HeaderInfo headerInfo = new HeaderInfo();
        headerInfo.setMerchantId(request.getHeader("merchantId"));
        headerInfo.setSerialNo(request.getHeader("serialNo"));
        headerInfo.setVersion(request.getHeader("version"));
        headerInfo.setSign(request.getHeader("sign"));
        headerInfo.setTimestamp(request.getHeader("timestamp"));
        return headerInfo;
    }

    public OpenAPIVerifyDTO openAPIVerify(HttpServletRequest request) {
        OpenAPIVerifyDTO openAPIVerifyDTO = new OpenAPIVerifyDTO();
        String merchantId = request.getHeader("merchantId");
        String version = request.getHeader("version");
        String sign = request.getHeader("sign");
        String timestamp = request.getHeader("timestamp");
        String serialNo = request.getHeader("serialNo");

        String appKey = null;
        if (StrUtil.isNotBlank(merchantId)) {

            UserCation userCation = callbackHelper.getRedisCation(merchantId);
            if (userCation == null) {
                openAPIVerifyDTO.setCode(OpenResponseCode.SYSTEM_EXCEPTION.getCode());
                openAPIVerifyDTO.setMsg("该appKey不存在");
                return openAPIVerifyDTO;
            }
            appKey = userCation.getAppId();
        }
        if (StrUtil.isEmpty(timestamp)) {
            log.info("请求头时间戳为空");
            openAPIVerifyDTO.setCode(OpenResponseCode.REQUEST_TIME_EXPIRED.getCode());
            openAPIVerifyDTO.setMsg(OpenResponseCode.REQUEST_TIME_EXPIRED.getCodeName());
            return openAPIVerifyDTO;
        }

        if (!NumberUtil.isInteger(timestamp)) {
            log.info("请求头时间戳非整型,timestamp: {}", timestamp);
            openAPIVerifyDTO.setCode(OpenResponseCode.REQUEST_TIME_EXPIRED.getCode());
            openAPIVerifyDTO.setMsg(OpenResponseCode.REQUEST_TIME_EXPIRED.getCodeName());
            return openAPIVerifyDTO;
        }

        int nowDate = (int) (System.currentTimeMillis() / 1000);
        if (!((Integer.parseInt(timestamp) - 360) <= nowDate && nowDate <= (Integer.parseInt(timestamp) + 360))) {
            log.info("当前系统校验时间戳误差超过6分钟,流水号为{}", serialNo);
            openAPIVerifyDTO.setCode(OpenResponseCode.REQUEST_TIME_EXPIRED.getCode());
            openAPIVerifyDTO.setMsg(OpenResponseCode.REQUEST_TIME_EXPIRED.getCodeName());
            return openAPIVerifyDTO;
        }


        if (StringUtils.isBlank(merchantId)) {
            //输出响应流
            log.error("拦截到的请求信息,merchantId为空");
            openAPIVerifyDTO.setCode(OpenResponseCode.SYSTEM_EXCEPTION.getCode());
            openAPIVerifyDTO.setMsg(OpenResponseCode.SYSTEM_EXCEPTION.getCodeName());
            return openAPIVerifyDTO;
        }

        if (StringUtils.isBlank(sign)) {
            //输出响应流
            log.error("拦截到的请求信息,sign为空,merchantId: {}", merchantId);
            openAPIVerifyDTO.setCode(OpenResponseCode.SIGN_ERROR.getCode());
            openAPIVerifyDTO.setMsg(OpenResponseCode.SIGN_ERROR.getCodeName());
            return openAPIVerifyDTO;
        }

        if (StringUtils.isBlank(version) || !"1.0".equals(version) || StringUtils.isBlank(timestamp)) {
            //输出响应流
            log.error("拦截到的请求信息,version不符合或者timestamp为空,merchantId: {},version: {},timestamp: {}", merchantId, version, timestamp);
            openAPIVerifyDTO.setCode(OpenResponseCode.SYSTEM_EXCEPTION.getCode());
            openAPIVerifyDTO.setMsg(OpenResponseCode.SYSTEM_EXCEPTION.getCodeName());
            return openAPIVerifyDTO;
        }


        if (StringUtils.isBlank(merchantId)) {
            //输出响应流
            log.error("拦截到的请求信息,merchantId的商户未配置appToken,marchantId: {}", merchantId);
            openAPIVerifyDTO.setCode(OpenResponseCode.MERCHANT_NOT_EXIST.getCode());
            openAPIVerifyDTO.setMsg(OpenResponseCode.MERCHANT_NOT_EXIST.getCodeName());
            return openAPIVerifyDTO;
        }

        // 解密
        // SM3(appKey+version+merchantId+timestamp+serialNo)，SM3国密算法，然后转成大写
        // 接口版本号表示，当前为固定值1.0
        assert appKey != null;
        String verifySign = UUID.getSign(appKey, merchantId, timestamp, version, serialNo);
        if (!verifySign.equals(sign)) {
            //输出响应流
            log.error("拦截到的请求信息,sign签名错误,merchantId: {},sign: {}, verifySign: {}", merchantId, sign, verifySign);
            openAPIVerifyDTO.setCode(OpenResponseCode.SIGN_ERROR.getCode());
            openAPIVerifyDTO.setMsg(OpenResponseCode.SIGN_ERROR.getCodeName());
            return openAPIVerifyDTO;
        }
        return openAPIVerifyDTO;
    }

}
